package com.jcgyl.export.shiro;
import java.util.LinkedHashMap;
import java.util.List;

import com.github.pagehelper.util.StringUtil;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

import com.jcgyl.export.dao.TbsysmenuDao;
import com.jcgyl.export.entity.Tbsysmenu;


/**
 * 
 * @author JL
 * shiro的配置
 *
 */

@Configuration  
public class ShiroConfig {  
	/**
	 * 获取application.properties中的数据
	 */
	@Value("${spring.redis.host}")  
	private String host;  
	@Value("${spring.redis.port}")  
	private int port;  
	@Value("${spring.redis.timeout}")  
	private int timeout;  
	@Value("${spring.redis.password}")  
	private String password;
	@Autowired
	private TbsysmenuDao tbsysmenuDao;
	/*
	 * Shiro生命周期处理器
	 */

	@Bean
	public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
		return new LifecycleBeanPostProcessor();
	}  
	/*
	 * shiro工厂bean配置
	 */
	@Bean(name="shiroFilter")
	public MyShiroFilterFactoryBean shiroFilter(org.apache.shiro.mgt.SecurityManager manager) {
		MyShiroFilterFactoryBean bean=new MyShiroFilterFactoryBean();
		bean.setSecurityManager(manager);
		//配置登录的url和登录成功的url
		// String url = request.getRequestURL().substring(0,request.getRequestURL().length()-request.getRequestURI().length())+;
		bean.setLoginUrl("/passport/login");
		bean.setSuccessUrl("/index");
		bean.setUnauthorizedUrl("/403");
		//配置访问权限
		LinkedHashMap<String, String> filterChainDefinitionMap=new LinkedHashMap<>();
		filterChainDefinitionMap.put("/passport/logout*","logout");
		filterChainDefinitionMap.put("/passport/login.html*", "anon"); //表示可以匿名访问
		filterChainDefinitionMap.put("/passport/*", "anon"); 
		filterChainDefinitionMap.put("/css/**","anon");
		filterChainDefinitionMap.put("/js/**","anon");
		filterChainDefinitionMap.put("/images/**","anon");
		filterChainDefinitionMap.put("/index.html*","authc");
		/*List<Tbsysmenu>list  = tbsysmenuDao.findObject();
		if(list.size()>0){
	        for(Tbsysmenu sysmenu :list){
	        	 if (StringUtil.isNotEmpty(sysmenu.getPageaddress())) {  
	                 //String permission = "perms[" + sysmenu.getPageaddress()+ "]";  
	                filterChainDefinitionMap.put(sysmenu.getPageaddress(),"authc");  
	            }  
	        }
		}*/
		filterChainDefinitionMap.put("/*", "authc");//表示需要认证才可以访问
		filterChainDefinitionMap.put("/**", "authc");//表示需要认证才可以访问
		filterChainDefinitionMap.put("/*.*", "authc");
		System.out.println("----------------------------------------->Shiro拦截器工厂类注入成功<-----------------------------------");
		bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
		return bean;
	}
	/*
	 * 配置shiro安全管理器
	 */
	@Bean(name="securityManager")
	public DefaultWebSecurityManager securityManager(@Qualifier("authRealm") MyRealm authRealm) {
		System.err.println("--------------shiro已经加载----------------");
		DefaultWebSecurityManager manager=new DefaultWebSecurityManager();
		manager.setRealm(authRealm);
		//manager.setSessionManager(sessionManager());
		//manager.setCacheManager(cacheManager());
		return manager;
	}


	//配置自定义的权限登录器
	@Bean(name="authRealm")
	public MyRealm authRealm() {
		MyRealm authRealm=new MyRealm();
		authRealm.setCredentialsMatcher(hashedCredentialsMatcher());
		return authRealm;
	}
	/**
	 * 凭证匹配器 （由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了  
	 * 所以我们需要修改下doGetAuthenticationInfo中的代码; ）  
	 */
	@Bean
	public HashedCredentialsMatcher hashedCredentialsMatcher() {
		HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
		hashedCredentialsMatcher.setHashAlgorithmName("MD5");//散列算法:这里使用MD5算法;
		hashedCredentialsMatcher.setHashIterations(1024);//散列的次数，比如散列两次，相当于 md5(md5(""));
		hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
		return hashedCredentialsMatcher;
	}


	@Bean
	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
		DefaultAdvisorAutoProxyCreator creator=new DefaultAdvisorAutoProxyCreator();
		creator.setProxyTargetClass(true);
		return creator;
	}
	/**
	 * shiro注解
	 * @param manager
	 * @return
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") org.apache.shiro.mgt.SecurityManager manager) {
		AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor();
		advisor.setSecurityManager(manager);
		return advisor;
	}
	/** 
	 * 配置shiro redisManager 
	 * <p> 
	 * 使用的是shiro-redis开源插件 
	 * 
	 * @return 
	 */  
	public RedisManager redisManager() {  
		RedisManager redisManager = new RedisManager();  
		redisManager.setHost(host);  
		redisManager.setPort(port);  
		redisManager.setExpire(1800);// 配置缓存过期时间  
		redisManager.setTimeout(timeout);  
		redisManager.setPassword(password);  
		return redisManager;  
	}  
	/** 
	 * cacheManager 缓存 redis实现 
	 * <p> 
	 * 使用的是shiro-redis开源插件 
	 * 
	 * @return 
	 */  
	@Bean  
	public RedisCacheManager cacheManager() {  
		RedisCacheManager redisCacheManager = new RedisCacheManager();  
		redisCacheManager.setRedisManager(redisManager());  
		return redisCacheManager;  
	}  
	/** 
	 * RedisSessionDAO shiro sessionDao层的实现 通过redis 
	 * <p> 
	 * 使用的是shiro-redis开源插件 
	 */  
	@Bean  
	public RedisSessionDAO redisSessionDAO() {  
		RedisSessionDAO redisSessionDAO = new RedisSessionDAO();  
		redisSessionDAO.setRedisManager(redisManager());  
		return redisSessionDAO;  
	}  
	/**
     * Session Manager
     * <p>
     * 使用的是shiro-redis开源插件
     */
    @Bean
    public MySessionManager sessionManager() {
    	MySessionManager sessionManager = new MySessionManager();
        sessionManager.setSessionDAO(redisSessionDAO());
        return sessionManager;
    }

	
	
	
	
	/*
	 *//**  
	 * cookie对象;  
	 * rememberMeCookie()方法是设置Cookie的生成模版，比如cookie的name，cookie的有效时间等等。  
	 * @return  
	 *//*  
   @Bean  
   public SimpleCookie rememberMeCookie(){  
         //System.out.println("ShiroConfiguration.rememberMeCookie()");  
         //这个参数是cookie的名称，对应前端的checkbox的name = rememberMe  
         SimpleCookie simpleCookie = new SimpleCookie("rememberMe");  
         //<!-- 记住我cookie生效时间30天 ,单位秒;-->  
         simpleCookie.setMaxAge(259200);  
         return simpleCookie;  
   }  
	  *//**  
	  * cookie管理对象;  
	  * rememberMeManager()方法是生成rememberMe管理器，而且要将这个rememberMe管理器设置到securityManager中  
	  * @return  
	  *//*  
   @Bean  
   public CookieRememberMeManager rememberMeManager(){  
         //System.out.println("ShiroConfiguration.rememberMeManager()");  
         CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();  
         cookieRememberMeManager.setCookie(rememberMeCookie());  
         //rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)  
         cookieRememberMeManager.setCipherKey(Base64.decode("2AvVhdsgUs0FSA3SDFAdag=="));  
         return cookieRememberMeManager;  
   }  
	   */
}  
